package com.yami.shop.common.util;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.MessageDigest;
import java.security.Security;
import java.util.*;


/**
 * 参数加解密工具
 * 
 * @author vic_miao 2019年6月3日 下午7:30:22
 */
public class ParamSignUtil {

	/**
	 * 获取随机key
	 * @param length
	 * @return
	 */
	public static String getRandomString(int length) { // length表示生成字符串的长度
		String base = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		Random random = new Random();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < length; i++) {
			int number = random.nextInt(base.length());
			sb.append(base.charAt(number));
		}
		return sb.toString();
	}

	/**
	 * 参数加密
	 * 
	 * @param content 内容
	 * @param key     加密可以
	 * @return
	 * @throws Exception
	 */
	public static String paramEncode(String content, String key) throws Exception {
		byte[] aesEncrypt = AES.aesEncrypt(content, key);
		String strTo16 = StringUtils.toHexString1(aesEncrypt);
		return strTo16;
	}

	/**
	 * 参数解密
	 * 
	 * @param content 密文
	 * @param key     解密key
	 * @return
	 * @throws Exception
	 */
	public static String paramDecode(String content, String key) throws Exception {
		byte[] bytes = hexStringToBytes(content);
		String decrypt = AES.aesDecrypt(bytes, key);
		return decrypt;
	}

	/**
	 * byte数组转为16进制字符串
	 * @param src
	 * @return
	 */
	public static String bytesToHexString(byte[] src) {
		StringBuilder stringBuilder = new StringBuilder("");
		if (src == null || src.length <= 0) {
			return null;
		}
		for (int i = 0; i < src.length; i++) {
			int v = src[i] & 0xFF;
			String hv = Integer.toHexString(v);
			if (hv.length() < 2) {
				stringBuilder.append(0);
			}
			stringBuilder.append(hv);
		}
		return stringBuilder.toString();
	}

	/**
	 * 16进制字符串转为byte数组
	 * @param hexString
	 * @return
	 */
	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		hexString = hexString.toUpperCase();
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
		}
		return d;
	}

	
	/**
	 * char转byte
	 * @param c
	 * @return
	 */
	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}
	
	/**
	 * 
	 * @Description: AES/CBC/PKCS7Padding加密
	 * @param content 待加密内容
	 * @param encrypyKey 加密秘钥
	 * @param iv 加密算法初始向量
	 * @return 加密后字符串-BASE64编码
	 */
	public static String aesCbcPKCS7PaddingEncrypt(final String content, final String encrypyKey, final String iv) {
		try {
			Security.addProvider(new BouncyCastleProvider());
			final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
			final Key sKeySpec = new SecretKeySpec(encrypyKey.getBytes("UTF-8"), "AES");
			final IvParameterSpec ivParameterSpec = new IvParameterSpec(iv.getBytes("UTF-8"));
			cipher.init(Cipher.ENCRYPT_MODE, sKeySpec, ivParameterSpec);
			final byte[] result = cipher.doFinal(content.getBytes("UTF-8"));
			return Base64Utils.encode(result);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 
	 * @Description: 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序），并且生成url参数串
	 * @param paramMap 要排序的Map对象
	 * @return
	 */
	public static String formatUrlMap(Map<String, Object> paramMap) {
        String buff = "";
        Map<String, Object> tmpMap = paramMap;
        try {
            List<Map.Entry<String, Object>> infoIds = new ArrayList<Map.Entry<String, Object>>(tmpMap.entrySet());
            // 对所有传入参数按照字段名的 ASCII 码从小到大排序（字典序）
            Collections.sort(infoIds, new Comparator<Map.Entry<String, Object>>() {
                @Override
                public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
                    return (o1.getKey()).toString().compareTo(o2.getKey());
                }
            });
            // 构造URL 键值对的格式
            StringBuilder buf = new StringBuilder();
            for (Map.Entry<String, Object> item : infoIds) {
            	String key = item.getKey();
                Object val = item.getValue();
                buf.append(key + "=" + val);
                buf.append("&");
            }
            buff = buf.toString();
            if (buff.isEmpty() == false) {
                buff = buff.substring(0, buff.length() - 1);
            }
        } catch (Exception e) {
           return null;
        }
        return buff;
    }  
	
	/**
	 * 
	 * @Description: SHA1实现
	 * @param inStr 原始字符串
	 * @return 运算后的字符串
	 * @throws Exception
	 */
    public static String shaEncode(String inStr) throws Exception {
        MessageDigest sha = null;
        try {
            sha = MessageDigest.getInstance("SHA1");
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
 
        byte[] byteArray = inStr.getBytes("UTF-8");
        byte[] md5Bytes = sha.digest(byteArray);
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int) md5Bytes[i]) & 0xff;
            if (val < 16) {
                hexValue.append("0");
            }
            hexValue.append(Integer.toHexString(val));
        }
        return hexValue.toString();
    }
}
